import { Button, Empty, Input, Message, Table } from '@arco-design/web-react';
import { IconDelete, IconPlus } from '@arco-design/web-react/icon';
import { HasPermission } from '@src/components/ability';
import LoadingMask from '@src/components/loadingMask';
import { MenuTypes } from '@src/components/mainNavBar';
import SearchBar from '@src/components/searchBar';
import { tooltipEllipsis } from '@src/components/tableColumn';
import TextButton from '@src/components/textButton';
import main from '@src/main';
import { AppStore } from '@src/types';
import usePageUtils from '@src/utils/pageUtils';
import { clearEmptyKey, onKeyEnter } from '@src/utils/utils';
import React, { useEffect, useState } from 'react';
import { shallowEqual, useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import { apiCreateCode, apiCreateCodeZip, apiSyncTable } from './api';
import ImportDBDialog from './comoponents/importDBDialog';
import PreViewDialog from './comoponents/preViewDialog';
import { Gen } from './types';

interface Props {
  currentRouteRecord: MenuTypes;
}

export default function CardGoodsTagListPage({ currentRouteRecord }: Props) {
  const pageUtils = usePageUtils({ model: 'code', table: 'gen', type: 'paginate' });
  const navigate = useNavigate();
  // 当前页面选中的数据列表
  const [tabSelectRows, setTabSelectRows] = useState<Gen[]>([]);
  // 导入表弹窗显示
  const [importDBDialogShow, setImportDBDialogShow] = useState(false);
  // 预览窗口
  const [previewDialogShow, setPreviewDialogShow] = useState<string>();
  /// ---------------搜索栏数据 --按页面要求修改------------
  const [tableName, settableName] = useState(pageUtils.params?.tableName ?? '');

  // 创建请求参数 及检索key 按页面要求修改
  function createParams() {
    return clearEmptyKey({
      dataName: 'master',
    });
  }

  // 当前页需要的数据
  const list = useSelector((state: AppStore) => state.paginate[pageUtils.stateKey], shallowEqual);

  // 需要随时刷新 创建参数的方法
  useEffect(() => {
    pageUtils.setFun(createParams);
  }, [createParams]); // eslint-disable-line

  // 页面初始化时请求数据
  useEffect(() => {
    pageUtils.handleRefreshData();
    main.setPageNum(pageUtils.pageTag, pageUtils.pageNum);
  }, []); //eslint-disable-line

  // 搜索
  function handleSearch() {
    setTabSelectRows([]);
    pageUtils.handleSearch();
  }

  // 重置
  function handleReset() {
    setTabSelectRows([]);
    settableName('');

    pageUtils.handleReset();
  }

  // 组合详情路由
  function createDetailRoutePath(record: Gen | string) {
    let id = typeof record === 'string' ? record : record.tableId;
    return currentRouteRecord.link!.replace('/index', '/detail') + '/' + id;
  }

  // 修改 操作列内的修改
  function handleEdit(record?: Gen) {
    if (record) {
      navigate(createDetailRoutePath(record));
    }
  }

  // 删除 弹窗确认
  async function handleDelete(record?: Gen) {
    let datas = record ? [record] : tabSelectRows || [];
    pageUtils.handleDelete(datas.map((i) => i.tableId!));
  }

  // 列表项有选择变动
  function handleTabSelectChange(selectedRowKeys: React.Key[], selectedRows: Gen[]) {
    setTabSelectRows(selectedRows);
  }

  // 列表项双击事件 一般是进详情
  function handleDoubleClick(record: Gen) {
    handleEdit(record);
  }

  ///-----------额外数据 / 方法-------------------
  // 同步数据库
  async function handleSync(record: Gen) {
    LoadingMask.show('正在同步...');
    try {
      let res = await apiSyncTable(record.tableName!);
      let data = res.data;
      if (data.code === 200) {
        Message.success(data.msg ?? '同步成功');
        pageUtils.handleRefreshData({ forceRefresh: true });
      } else {
        Message.warning(data.msg ?? '同步失败');
      }
    } catch (e: any) {
      Message.error(e.message ?? '同步失败');
    } finally {
      LoadingMask.hide();
    }
  }

  // 生成代码
  async function handleCreateCode(record?: Gen) {
    let datas = record ? [record] : tabSelectRows || [];
    if (!datas.length) {
      return Message.warning('请选择要生成的数据');
    }
    LoadingMask.show('正在生成...');
    try {
      if (record?.genType === '1') {
        let res = await apiCreateCode(datas.map((i) => i.tableName!).join(','));
        let data = res.data;
        if (data.code === 200) {
          Message.success(data.msg ?? '生成成功');
        } else {
          Message.warning(data.msg ?? '生成失败');
        }
      } else {
        await apiCreateCodeZip(datas.map((i) => i.tableName!).join(','));
      }
    } catch (e: any) {
      Message.error(e.message ?? '生成失败');
    } finally {
      LoadingMask.hide();
    }
  }
  ///-------------------------------------

  let dataSource: Gen[] = list?.results || [];
  dataSource = dataSource.map((item) => Object.assign({}, item, { key: item.tableId! }));
  // 定义表格内的列
  const columns = [
    {
      title: '序号',
      dataIndex: 'tableId',
      key: 'tableId',
    },
    {
      title: '表名',
      dataIndex: 'tableName',
      key: 'tableName',
    },
    {
      title: '表描述',
      dataIndex: 'tableComment',
      key: 'tableComment',
    },
    {
      title: '实体',
      dataIndex: 'className',
      key: 'className',
    },
    {
      title: '模块名',
      dataIndex: 'moduleName',
      key: 'moduleName',
    },
    {
      title: '业务名',
      dataIndex: 'businessName',
      key: 'businessName',
    },
    {
      title: '生成路径',
      dataIndex: 'packageName',
      key: 'packageName',
      render: (v: string) => tooltipEllipsis(v, 'w-100'),
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
      key: 'createTime',
    },
    {
      title: '操作',
      render: (_: any, record: Gen) => (
        <div className="d-flex-r jc-start text-primary-color">
          <TextButton text="编辑" onClick={() => handleEdit(record)} />
          <TextButton text="同步" onClick={() => handleSync(record)} />
          <TextButton text="预览" onClick={() => setPreviewDialogShow(record.tableId)} />
          <TextButton text="生成代码" onClick={() => handleCreateCode(record)} />
          <TextButton text="删除" red onClick={() => handleDelete(record)} />
        </div>
      ),
    },
  ];

  return (
    <div className="page list-page">
      <SearchBar onConfirm={handleSearch} onReset={handleReset}>
        <Input
          allowClear
          className="mr-20 mb-20 search-input"
          onKeyUp={onKeyEnter(handleSearch)}
          placeholder="表名称"
          value={tableName}
          onChange={(v) => settableName(v)}
        />
      </SearchBar>
      <div className="page-content m-20">
        <div className="action-bar">
          <div className="flex-1" />
          <Button icon={<IconPlus />} className="ml-20" type="primary" onClick={() => handleCreateCode()}>
            生成代码
          </Button>
          <Button icon={<IconPlus />} className="ml-20" type="primary" onClick={() => setImportDBDialogShow(true)}>
            导入表
          </Button>
          <HasPermission permission={['card:cardGoodsTag:add']}>
            <Button icon={<IconPlus />} className="ml-20" type="primary" onClick={() => handleEdit()}>
              新增
            </Button>
          </HasPermission>

          <HasPermission permission={['card:cardGoodsTag:remove']}>
            <Button
              icon={<IconDelete />}
              className="ml-20"
              type="primary"
              status="danger"
              onClick={() => handleDelete()}
            >
              删除
            </Button>
          </HasPermission>
        </div>
        <Table
          className="table"
          rowSelection={{ type: 'checkbox', onChange: handleTabSelectChange }}
          data={dataSource}
          columns={columns}
          pagination={{
            className: 'pagination-block',
            total: list?.total || 1,
            current: pageUtils.pageNum,
            pageSize: pageUtils.pageSize,
            showJumper: true,
            sizeOptions: pageUtils.defaultPageSizeOptions,
            showTotal: (total) => '共' + total + '条',
            size: 'small',
            onChange: pageUtils.handlePageAndSizeChange,
          }}
          noDataElement={<Empty description={list?.error ?? '暂无数据'} />}
          loading={!list || (list?.fetching && !list?.loaded)}
          onRow={(record) => ({
            onDoubleClick: () => handleDoubleClick(record),
          })}
        />
      </div>
      {importDBDialogShow && (
        <ImportDBDialog
          onClose={(v?: boolean) => {
            setImportDBDialogShow(false);
            if (v) {
              pageUtils.handleRefreshData({ forceRefresh: true });
            }
          }}
        />
      )}
      {!!previewDialogShow && (
        <PreViewDialog tableId={previewDialogShow} onClose={() => setPreviewDialogShow(undefined)} />
      )}
    </div>
  );
}
